/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the
 * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
 
package com.cburch.logisim.proj;

public abstract class Action {
	
	/**
	 * Class used to append two <code>Action</code> objects.
	 */
    private static class UnionAction extends Action {
        Action first;
        Action second;

        /**
         * Set the two <code>Action</code> objects.
         * @param first <code>Action</code>
         * @param second <code>Action</code>
         */
        UnionAction(Action first, Action second) {
            this.first = first;
            this.second = second;
        }

        /**
         * Not used.
         * Indicates if either <code>Action</code> is a modification.
         */
        public boolean isModification() {
            return first.isModification() || second.isModification();
        }

        /**
         * Returns the name of the first <code>Action</code>.
         * @return <code>String</code> name
         */
        public String getName() { return first.getName(); }

        /**
         * Performs the first <code>Action</code> and the second <code>Action</code>.
         * @param proj <code>Project</code> to perform the <code>Action</code> on
         */
        public void doIt(Project proj) {
            first.doIt(proj);
            second.doIt(proj);
        }

        /**
         * Performs the undo action for both <code>Action</code> objects.
         * @param proj <code>Project</code> to undo the <code>Action</code> on
         */
        public void undo(Project proj) {
            second.undo(proj);
            first.undo(proj);
        }
    }

    /**
     * Not used.
     * Indicates if the <code>Action</code> is a modification.
     * @return <code>Boolean</code>
     */
    public boolean isModification() { return true; }

    /**
     * Returns the name of the <code>Action</code>.
     * @return <code>String</code> name of the <code>Action</code>
     */
    public abstract String getName();

    /**
     * Perform the <code>Action</code>.
     * @param proj <code>Project</code> to perform the <code>Action</code> on
     */
    public abstract void doIt(Project proj);

    /**
     * Undoes the <code>Action</code>.
     * @param proj <code>Project</code> to undo
     */
    public abstract void undo(Project proj);

    
    /**
     * Determines if the parameter <code>Action</code> should be appended to the <code>Action</code>.
     * @param other <code>Action</code> to test if it should be appended
     * @return <code>Boolean</code> indicating if the <code>Action</code> sould be appended
     */
    public boolean shouldAppendTo(Action other) { return false; }

    /**
     * Appends the <code>Action</code> other to the current <code>Action</code>.
     * @param other <code>Action</code> to append
     * @return <code>Action</code> consisting of the new <code>Actions</code>
     */
    public Action append(Action other) {
        return new UnionAction(this, other);
    }

}
